#define ANS
#ifdef ANS
#include <cstring>
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 120000;
const int tk = 4;
char s[30],str[1010];
struct node {
     int fail,danger;
     int nxt[tk];
     void init(){
          fail = -1; danger = 0;
          memset(nxt,0,sizeof(nxt));
     }
}trie[N];
int top,q[N];
int f[1010][1010];
inline int idx(char c) {
     if(c == 'A')  return 0;
     else if(c == 'G') return 1;
     else if(c == 'C') return 2;
     return 3;
}
inline void ini() {
     top = 1;
     trie[0].init();
}
void ins(char *str) {
     int p = 0;
     for(int i=0;str[i];i++) {
         int k = idx(str[i]);
         if( !trie[p].nxt[k] ) {
              trie[top].init();
              trie[p].nxt[k] = top++;
         }
         p = trie[p].nxt[k];
     }
     trie[p].danger = 1;
}
void ac() {
     int v,*s = q,*e = q, p, f;
     *e ++ = 0;
     while(s != e) {
          p = *s ++;
          for(int i=0;i<tk;i++) {
               if(trie[p].nxt[i]) {
                   f = trie[p].fail;
                   v = trie[p].nxt[i];
                   if(p == 0) trie[v].fail = 0;
                   else trie[v].fail = trie[f].nxt[i];
                   if(f!=-1 && trie[trie[f].nxt[i]].danger) trie[v].danger = 1;  //如果fail节点是危险的，那么本节点也是危险的
                   *e ++ = v;
               } else {
                   int f = trie[p].fail;
                   if(p == 0) trie[p].nxt[i] = 0;
                   else trie[p].nxt[i] = trie[f].nxt[i];
               }
          }
     }
}
inline int min(int x,int y) {
    if(x == -1) return y;
    if(y == -1) return x;
    return x>y?y:x;
}
int dp(char *str) {
     memset(f,-1,sizeof(f));
     int i,k,v;
     f[0][0] = 0;
     for(i=1;str[i];i++) {
          for(int j=0;j<top;j++) {
              if(f[i-1][j] != -1) {
                  for(int k=0;k<4;k++) {
                      v = trie[j].nxt[k];
                      if(trie[v].danger == 0) {
                           f[i][v] = min(f[i][v], f[i-1][j] + (k != idx(str[i])));
                      }
                  }
              }
          }
     }
     return i-1;
}
int main() {
	#ifdef DEBUG
		freopen("in.txt", "rt", stdin);
	#endif
    int n,ca=1;
    while(scanf("%d",&n) , n) {
          ini();
          while(n --) { scanf("%s",s); ins(s); }
          ac();

          scanf("%s",str+1);

          int ans = -1,len=dp(str);

          for(int j=0;j<top;j++) {
                if(!trie[j].danger) ans = min(ans,f[len][j]);
          }
          printf("Case %d: %d\n",ca++,ans);
    }
    return 0;
}

#else

#include <vector>
#include <string>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <climits>
#include <algorithm>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
using namespace std;
const int MAXN = 1e4;
const int INVALID_VALUE = -2;
struct CACAutoMatcher {
	struct CNode {
		CNode *down, *next, *prev, *father;
		int no;
		int end;
		char v;
	};
	CNode nodes[MAXN];
	int nodeCnt;
	CNode *root;
	void reset() {
		nodeCnt = 0;
		root = newNode(NULL);
	}
	CNode *newNode(CNode *fa) {
		CNode &cur = nodes[nodeCnt];
		cur.no = nodeCnt;
		cur.end = 0;
		cur.down = cur.next = cur.prev = NULL;
		cur.father = fa;
		cur.v = 0;
		++nodeCnt;
		return &cur;
	}
	void build(char *s) {
		dfsBild(s, root);
	}
	void dfsBild(char *s, CNode *rt) {
		CNode *p = rt->down;
		if(rt->down == NULL) {
			p = rt->down = newNode(rt);
			p->v = *s;
		}
		while(p->v != *s) {
			if(p->next != NULL) {
				p = p->next;
			} else {
				p->next = newNode(rt);
				p = p->next;
				p->v = *s;
			}
		}
		if(s[1]) {
			dfsBild(s+1, p);
		} else {
			p->end = 1;
		}
	}
	int vj[10000];
	int vjCnt;
	void init() {
		for(CNode *p = root->down; p != NULL; p = p->next) {
			dfsInit(p, root);
		}
		vjCnt = 0;
		for(int i = 0; i < nodeCnt; ++i) {
			if(nodes[i].end > 0) continue;
			vj[vjCnt++] = i;
		}
	}
	CNode *findChild(CNode *pi, char v) {
		for(CNode *pii = pi->down; pii != NULL; pii = pii->next) {
				if(pii->v == v) return pii;
			}
		return NULL;
	}
	CNode *findPrev(CNode *p, CNode *father) {
		for(CNode *pi = father->prev; pi != NULL; pi = pi->prev) {
			CNode *nd = findChild(pi, p->v);
			if(nd) return nd;
		}
		return root;
	}

	void dfsInit(CNode *p, CNode *father) {
		p->father = father;
		p->prev = findPrev(p, father);
		if(father->end) {
			p->end = father->end + 1;
		}
		for(CNode *pi = p->down; pi != NULL; pi = pi->next) {
			dfsInit(pi, p);
		}
	}


	char mp[5];
	CACAutoMatcher() {
		mp = {'A','C','G','T'};
	}

	void update(int id, int s, int v) {
		if(dpData[id][s] == -1 || dpData[id][s] > v) {
			dpData[id][s] = v;
			if(v == 1 && id == 1) {
				int cc = 1;
			}
		}
	}

	int dpData[1000][1000];
	int dpExecute() {
		for(int k = 0; k < 4; ++k) {
			CNode *node = findChild(root, mp[k]);
			if(node && node->end)continue;
			if(node) {
				update(0, node->no, s[0] == mp[k]?0:1);
			} else {
				update(0, 0, s[0] == mp[k]?0:1);
			}
		}

		for(int i = 1; s[i]; ++i) {
			for(int ji = 0; ji < vjCnt; ++ji) {
				const int &j = vj[ji];
				//if(nodes[j])
				if(i == 3 && j == 4) {
					int aa = 1;
				}
				int cur = dpData[i-1][j];
				if(cur == 0) {
					int xxx = 1;
				}
				if(cur == -1) continue;
				for(int k = 0; k < 4; ++k) {
					const char &ch = mp[k];
					bool flag = true;
					if(i==1 && j == 2 && k ==3) {
						int ss = 1;
					}
					for(CNode *pi = nodes+j; pi != NULL; pi = pi->prev) {
						CNode *pii = findChild(pi, ch);
						if(pii && pii->end) {
							flag = false;
							break;
						}
					}
					int goal = 0;
					if(flag) {
						for(CNode *pi = nodes+j; pi != NULL; pi = pi->prev) {
							CNode *pii = findChild(pi, ch);
							if(pii) {
								goal = pii->no;
								flag = false;
								break;
							}
						}
					}

					if(flag) {
						update(i, goal, cur + ch!=s[i]);
					}
					int dccc = 1;
				}
			}
		}
		int ret = INT_MAX;
		for(int j = 0; j < nodeCnt; ++j) {
			if(dpData[len-1][j]==-1) continue;

			ret = min(ret, dpData[len-1][j]);
			if(ret == 0) {
				int aaa = 1;
			}
		}
		return ret;
	}
	int len;
	char s[10000];
	int getAns() {
		len = strlen(s);
		memset(dpData, -1, sizeof(dpData));
		int ret = dpExecute();
		if(ret == INT_MAX) return -1;
		return ret;
	}
};






struct CProblem {
	CACAutoMatcher tree;
	char buf[1000];
    void printAns(int n) {
		tree.reset();
		for(int i = 0; i < n; ++i) {
			scanf("%s", buf);
			tree.build(buf);
		}
		tree.init();
		scanf("%s", tree.s);
		int ans = tree.getAns();
		printf("%d\n", ans);
    }
};

int main() {
#ifdef DEBUG
    freopen("in.txt", "rt", stdin);
#endif
    static CProblem cp;
    static char s[10000000];
    int t;
    while(scanf("%d", &t), t) {
        cp.printAns(t);
    }
    return 0;
}
#endif
